package com.capsulode.excel.conversion.impl;

import com.capsulode.excel.conversion.Converter;
import com.capsulode.excel.exception.CellTypeNotExpectException;
import com.capsulode.excel.exception.ConversionFailException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;

public class DateConverter implements Converter<Date> {
    private final SimpleDateFormat formatter;

    public DateConverter(String pattern) {
        formatter = new SimpleDateFormat(pattern.length() > 0 ? pattern : "yyyy-MM-dd");
    }

    @Override
    public Date convert(Cell cell) throws ConversionFailException, CellTypeNotExpectException {

        if (CellType.STRING.equals(cell.getCellTypeEnum())) {
            String trim = cell.getStringCellValue().trim();
            if (trim.isEmpty()) {
                return null;
            }
            try {
                return formatter.parse(cell.getStringCellValue().trim());
            } catch (ParseException ex) {
                throw new ConversionFailException(cell.getRowIndex(), cell.getColumnIndex(), "无法识别的日期格式：" + cell, ex);
            }
        }

        if (CellType.NUMERIC.equals(cell.getCellTypeEnum())) {
            try {
                return cell.getDateCellValue();
            } catch (NumberFormatException ex) {
                throw new ConversionFailException(cell.getRowIndex(), cell.getColumnIndex(), "无法识别的日期格式：" + cell, ex);
            }
        }

        if (CellType.BLANK.equals(cell.getCellTypeEnum())) {
            return null;
        }

        throw new CellTypeNotExpectException(cell.getRowIndex(), cell.getColumnIndex());
    }

    @Override
    public void serialize(Object value, Cell cell) throws ConversionFailException, CellTypeNotExpectException {
        if (value instanceof Date) {
            cell.setCellValue((Date) value);
            return;
        }
        if (value instanceof LocalDate) {
            Instant instant = ((LocalDate) value)
                    .atStartOfDay()
                    .atZone(ZoneId.systemDefault())
                    .toInstant();
            cell.setCellValue(Date.from(instant));
            return;
        }
        if (value instanceof LocalDateTime) {
            Instant instant = ((LocalDateTime) value)
                    .atZone(ZoneId.systemDefault())
                    .toInstant();
            cell.setCellValue(Date.from(instant));
            return;
        }
        if (value instanceof Calendar) {
            cell.setCellValue((Calendar) value);
            return;
        }
        if (value instanceof Number) {
            Date val = new Date(((Number) value).longValue());
            cell.setCellValue(val);
            return;
        }
        if (value instanceof CharSequence) {
            try {
                Date val = formatter.parse(value.toString());
                cell.setCellValue(val);
            } catch (ParseException ex) {
                throw new ConversionFailException(cell.getRowIndex(), cell.getColumnIndex(), "无法识别的日期格式：" + cell, ex);
            }
            return;
        }
        throw new CellTypeNotExpectException(cell.getRowIndex(), cell.getColumnIndex());
    }
}
